from dataclasses import dataclass

from PySide2.QtCore import Qt
from PySide2.QtGui import QColor, QPalette
from PySide2.QtWidgets import QTableWidgetItem, QTableWidget

from common.pyside2_table.qt_wgt import ButtonWithLink, Model_Combobox


@dataclass
class ColItem:
    # table: QTableWidget = QTableWidget()
    """
    widget_type:str = "item"  "cmb"
    father_type:str = "obj"    "dic" , "str", "list"
    """

    col_name: str = None  # 列名
    col_nickname: str = None  # 别名（显示名称）
    widget_type: str = "item"  #
    father_type: str = "obj"
    value_attr_name: str = col_name
    is_hide: bool = False  # 是否隐藏
    is_edit: bool = False  # 是否可编辑
    col_width: int = 0  # 列宽
    col_value: object = None
    col_fun: object = None

    def get_value(self, model):
        """获取对象中的值"""
        return get_value_from_obj(model, self.value_attr_name, self.father_type)

    def set_value(self, model, value):
        """把数据传递给对象"""
        return set_value_to_obj(model, value, self.value_attr_name, self.father_type)


def add_to_table(table: QTableWidget, model_item: ColItem, model, cell):
    if model_item.widget_type == "item":
        add_model_label(table, model_item, cell, model)
    elif model_item.widget_type == "cmb":
        add_model_cmb(table, model_item, cell, model)
    elif model_item.widget_type == "btn":
        add_model_btn(table, model_item, cell, model)


def add_model_cmb(table: QTableWidget, model_item: ColItem, cell, model):
    """
    para: {option_list,model,change_func}
    """

    value = model_item.get_value(model)
    if model_item.col_value:
        options = model_item.col_value
    else:
        options = ["所有"]
    q_cmb = Model_Combobox()
    q_cmb.col_name = model_item.col_name
    q_cmb.row_index = cell[0]
    q_cmb.addItems(options)
    q_cmb.model = model
    if model_item.col_fun:
        q_cmb.currentTextChanged.connect(lambda text: model_item.col_fun(text))
    else:
        q_cmb.currentTextChanged.connect(
            lambda text: table.add_value_to_change_dic(text, q_cmb.row_index, model_item.value_attr_name))

    if value and value in options:
        q_cmb.setCurrentText(value)
        if not table.is_original:
            palette = QPalette()
            palette.setColor(QPalette.Text, QColor("blue"))

    table.setCellWidget(*cell, q_cmb)


def add_model_btn(table: QTableWidget, btn_item: ColItem, cell, model):
    if btn_item.col_value:
        btn_name = btn_item.col_value
    else:
        btn_name = btn_item.col_nickname
    value = btn_item.get_value(model)
    if btn_item.col_fun:
        value = btn_item.col_fun(value)
    btn = ButtonWithLink(btn_name, value)
    table.setCellWidget(*cell, btn)


def add_model_label(table, lb_item: ColItem, cell, model):
    value = lb_item.get_value(model)

    table.setItem(*cell, QTableWidgetItem(str(value)))
    table_item: QTableWidgetItem = table.item(*cell)
    if not lb_item.is_edit:
        set_item_no_edit(table_item)


def set_value_to_obj(model, value, value_attr_name, father_type="obj"):
    if father_type == "obj":
        setattr(model, value_attr_name, value)

    elif father_type in ["dic", "list", "df"]:
        if father_type != "df":
            model[value_attr_name] = value
    else:
        model = value
    return model


def get_value_from_obj(model, value_attr_name, father_type="obj"):
    if father_type == "obj":
        value = getattr(model, value_attr_name)

    elif father_type in ["dic", "list"]:
        value = model[value_attr_name]
    else:
        value = model
    if not value:
        value = ""
    return value


def set_item_no_edit(wtg_item: QTableWidgetItem):
    """设置单元格是不可编辑"""

    if not wtg_item:
        assert False, "没有控件"
    editable = False
    wtg_item.setFlags(wtg_item.flags() & ~Qt.ItemIsEditable) if not editable else wtg_item.setFlags(
        wtg_item.flags() | Qt.ItemIsEditable)
    # 设置为不可编辑
    wtg_item.setData(Qt.ForegroundRole, QColor('black'))  # 文本颜色
    wtg_item.setData(Qt.BackgroundRole, QColor(240, 240, 240))  # 背景色
